﻿#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    // 设置窗口属性,无边框
    this->setWindowFlag(Qt::FramelessWindowHint);

    // 右键菜单
    m_pExitAct = new QAction();
    m_pMenu = new QMenu(this);
    m_pExitAct->setText("退出");
    m_pExitAct->setIcon(QIcon(":/close.ico"));
    m_pMenu->addAction(m_pExitAct);
    connect(m_pExitAct, SIGNAL(triggered(bool)), this, SLOT(slot_exitApp()));

    // 设置天气预报字体颜色
    ui->weatherLB->setStyleSheet("QLabel{font:15pt;background-color:rgb(255,255,255,0);color:rgb(85,255,0);}");
    ui->tempLB->setStyleSheet("QLabel{font:30pt;}");
    ui->ganmaoTextBrowser->setStyleSheet("background: transparent; border: none; color: white;");

    // QList重载的链表append操作
    forecast_week_list << ui->weekLB0 << ui->weekLB1 << ui->weekLB2 << ui->weekLB3 << ui->weekLB4 << ui->weekLB5;
    forecast_date_list << ui->dateLB0 << ui->dateLB1 << ui->dateLB2 << ui->dateLB3 << ui->dateLB4 << ui->dateLB5;
    forecast_type_list << ui->typeLB0 << ui->typeLB1 << ui->typeLB2 << ui->typeLB3 << ui->typeLB4 << ui->typeLB5;
    forecast_typeIco_list << ui->typeicoLB0 << ui->typeicoLB1 << ui->typeicoLB2 << ui->typeicoLB3 << ui->typeicoLB4 << ui->typeicoLB5;
    forecast_aqi_list << ui->qualityLB0 << ui->qualityLB1 << ui->qualityLB2 << ui->qualityLB3 << ui->qualityLB4 << ui->qualityLB5;
    forecast_high_list << ui->highLB0 << ui->highLB1 << ui->highLB2 << ui->highLB3 << ui->highLB4 << ui->highLB5;
    forecast_low_list << ui->lowLB0 << ui->lowLB1 << ui->lowLB2 << ui->lowLB3 << ui->lowLB4 << ui->lowLB5;

    // 调整样式
    for(int i = 0; i < 6; i++) {
        forecast_week_list[i]->setStyleSheet("background-color:rgb(0,255,255,100);");
    }
    for(int i = 0; i < 6; i++) {
        forecast_date_list[i]->setStyleSheet("background-color:rgb(0,255,255,100);");
    }
    for(int i = 0; i < 6; i++) {
        forecast_aqi_list[i]->setStyleSheet("font:8pt");
    }
    ui->cityLineEdit->setStyleSheet("QLineEdit{border:1px solid gray; border-radius:4px; background:argb(47,47,47,130);\
color:rgb(255,255,255);} QLineEdit:hover{border-color:rgb(101,255,106);}");

    // 私有属性初始化
    url = "http://t.weather.itboy.net/api/weather/city/";
    city = u8"合肥";
    cityTmp = city;
    manager = new QNetworkAccessManager(this);
    connect(manager, SIGNAL(finished(QNetworkReply*)), \
            this, SLOT(replayFinished(QNetworkReply*)));
    getWeatherInfo(manager);

    // 添加事件过滤
    // 当ui->sunRiseSetLB接收到事件（例如绘制事件等）时，Qt会先调用Widget对象的 eventFilter() 方法
    ui->sunRiseSetLB->installEventFilter(this);
    ui->curveLB->installEventFilter(this);
    ui->cityLineEdit->installEventFilter(this);

    // 定时器update日出日落曲线
    sunTimer = new QTimer(ui->sunRiseSetLB);
    connect(sunTimer, SIGNAL(timeout()), ui->sunRiseSetLB, SLOT(update()));
    connect(sunTimer, SIGNAL(timeout()), ui->curveLB, SLOT(update()));
    sunTimer->start(1000);
}

    // 控件重新绘制（利用样式表绘制widget背景）
void Widget::paintEvent(QPaintEvent* event)
{
    QStyleOption opt;
    opt.init(this);
    QPainter p(this);
    style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
    QWidget::paintEvent(event);
}

void Widget::contextMenuEvent(QContextMenuEvent *menuEvent)
{
    m_pMenu->exec(QCursor::pos());
    menuEvent->accept();
}

void Widget::mousePressEvent(QMouseEvent *event)
{
    // 鼠标按下事件坐标点位置
    // 屏幕坐标减去程序坐标
    m_pos = event->globalPos() - this->pos();
}

void Widget::mouseMoveEvent(QMouseEvent *event)
{
    this->move(event->globalPos() - m_pos);
}

void Widget::slot_exitApp()
{
    qApp->exit();
}

void Widget::replayFinished(QNetworkReply* reply)
{
    QVariant status_code = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
    if(reply->error() != QNetworkReply::NoError || status_code != 200) {
        QMessageBox::warning(this, u8"错误", u8"请求数据错误，检查网络连接");
        return;
    }

    QByteArray bytes = reply->readAll();
    parseToJson(bytes);
}

void Widget::getWeatherInfo(QNetworkAccessManager *manager)
{
    QString citycode = m_weatherTool[city];
    if(citycode == "000000000") {
        QMessageBox::warning(this, u8"错误，指定城市不存在", u8"指定城市不存在");
        return;
    }
    QUrl jurl(url + citycode);
    manager->get(QNetworkRequest(jurl));
}

void Widget::parseToJson(QByteArray arr)
{
    // 字节数据转换为json
    QJsonParseError err;
    QJsonDocument jsDoc = QJsonDocument::fromJson(arr, &err);
    if(err.error != QJsonParseError::NoError) {
        return;
    }

    // json转换为object
    QJsonObject jObject = jsDoc.object();
    // object转换为qstring
    QString mess = jObject.value("message").toString();
    qDebug() << mess;
    if(mess.contains("success") == false) {
        QMessageBox::warning(this, u8"错误", u8"访问城市不存在");
        city = cityTmp; // 恢复上次访问的城市
        return;
    }

    // 提取有用数据
    today = jObject;
    forecast[0] = jObject.value("data").toObject().value("yesterday").toObject();
    QJsonArray foreArr = jObject.value("data").toObject().value("forecast").toArray();
    int j = 0;
    for(int i = 1; i < 6; ++i) {
        forecast[i] = foreArr.at(j).toObject();
        j++;
    }
    // 设置当天数据
    setTodayLabelContent();
    // 设置预测数据
    setForecastLabelContent();
}

void Widget::setTodayLabelContent()
{
    ui->dateLB->setText(today.date);
    ui->tempLB->setText(today.temp + "℃");
    ui->locLB->setText(today.city);
    ui->rightLB->setText(today.type);
    ui->qualityLB->setText(today.quality);
    ui->noticeLB->setText(today.notice);
    ui->shiduLB->setText(today.shidu);
    ui->pm25LB->setText(today.pm25);
    ui->fxLB->setText(today.fx);
    ui->flLB->setText(today.fl);
    ui->ganmaoTextBrowser->setText(today.ganmao);
    ui->weathericoLB->setStyleSheet(tr("image:url(:/day/%1.png)").arg(today.type));
}

void Widget::setForecastLabelContent()
{
    for(int i = 0; i < 6; i++) {
        forecast_week_list[i]->setText(forecast[i].week);
        forecast_date_list[i]->setText(forecast[i].date);
        forecast_type_list[i]->setText(forecast[i].type);      // 天气
        forecast_typeIco_list[i]->setStyleSheet(tr("image:url(:/day/%1.png);").arg(forecast[i].type));   // 天气图标
        forecast_high_list[i]->setText(forecast[i].high.split(" ").at(1));      // 高温
        forecast_low_list[i]->setText(forecast[i].low.split(" ").at(1));       // 低温
        if(forecast[i].aqi.toInt() >= 0 && forecast[i].aqi.toInt() <= 50) {
            forecast_aqi_list[i]->setText(u8"优质");
            forecast_aqi_list[i]->setStyleSheet("color:rgb(0, 255, 0);");
        }
        else if(forecast[i].aqi.toInt() > 50 && forecast[i].aqi.toInt() <= 100) {
            forecast_aqi_list[i]->setText(u8"良好");
            forecast_aqi_list[i]->setStyleSheet("color:rgb(255, 255, 0);");
        }
        else if(forecast[i].aqi.toInt() > 100 && forecast[i].aqi.toInt() <= 150) {
            forecast_aqi_list[i]->setText(u8"轻度污染");
            forecast_aqi_list[i]->setStyleSheet("color:rgb(255, 170, 0);");
        }
        else if(forecast[i].aqi.toInt() > 150 && forecast[i].aqi.toInt() <= 200) {
            forecast_aqi_list[i]->setText(u8"重度污染");
            forecast_aqi_list[i]->setStyleSheet("color:rgb(255, 0, 0);");
        }
        else  {
            forecast_aqi_list[i]->setText(u8"重度污染");
            forecast_aqi_list[i]->setStyleSheet("color:rgb(170, 0, 0);");
        }
    }
    forecast_week_list[0]->setText("昨天");
    forecast_week_list[1]->setText("今天");
}

const QPoint Widget::sun[2]{
    QPoint(10, 75),
    QPoint(160, 75)
};
const QRect Widget::sunRiseSet[2]{
    QRect(0, 70, 50,  20),
    QRect(120, 70, 50, 20)
};
const QRect Widget::rect[2] {
    QRect(10, 0, 150, 150),
    QRect(50, 70, 70, 20)
};

// 画日出日落曲线
void Widget::paintSunRiseSet()
{
    QPainter painter(ui->sunRiseSetLB);
    painter.setRenderHint(QPainter::Antialiasing, true);    // 反锯齿
    painter.save(); // 保存当前状态 推送堆栈

    QPen pen = painter.pen();
    pen.setWidth(0.5);
    pen.setColor(Qt::yellow);

    painter.setPen(pen);
    painter.drawLine(sun[0], sun[1]);

    painter.restore();
    painter.save();

    painter.setFont(QFont("Microsoft Yahei", 8, QFont::Normal));
    painter.setPen(Qt::white);

    if(today.sunrise != "" && today.sunset != "") {
        painter.drawText(sunRiseSet[0], Qt::AlignHCenter, today.sunrise);
        painter.drawText(sunRiseSet[1], Qt::AlignHCenter, today.sunset);
    }
    painter.drawText(rect[1], Qt::AlignHCenter, u8"日出日落");
    painter.restore();
    painter.save();
    pen.setWidth(0.5);
    pen.setStyle(Qt::DotLine);  // 虚线
    pen.setColor(Qt::green);
    painter.setPen(pen);
    painter.drawArc(rect[0], 0*16, 180*16);
    // 调用一次restore就要调用一次save
    painter.restore();
    painter.save();

    // 使用刷子绘制日出日落占比
    if(today.sunrise != "" && today.sunset != "") {
        painter.setPen(Qt::NoPen);
        painter.setBrush(QColor(255, 85, 0, 100));

        int startAngle, spanAngle;
        QString sunsetTime = today.date + " " + today.sunset;

        if(QDateTime::currentDateTime() > QDateTime::fromString(sunsetTime, "yyyy-MM-dd hh::mm")){
            startAngle = 0 * 16;
            spanAngle = 180 * 16;
        } else {
            QStringList sunRiseTime = today.sunrise.split(":");
            QStringList sunSetTime = today.sunset.split(":");

            QString sunRiseTimeHour = sunRiseTime.at(0);
            QString sunRiseTimeMinute = sunRiseTime.at(1);

            QString sunSetTimeHour = sunsetTime.at(0);
            QString sunSetTimeMinute = sunsetTime.at(1);

            // 纯分钟
            int sunRise = sunRiseTimeHour.toInt() *60 + sunRiseTimeMinute.toInt();
            int sunSet = sunSetTimeHour.toInt() * 60 + sunSetTimeMinute.toInt();
            // 当前时间纯分钟
            int now = QTime::currentTime().hour()*60 + QTime::currentTime().minute();

            startAngle = ((double)(sunSet-now)/(sunSet - sunRise)) * 180 * 16;
            spanAngle = ((double)(now - sunRise)/(sunSet - sunRise)) * 180 * 16;
        }

        if(startAngle >= 0 && spanAngle >= 0 ) {
            painter.drawPie(rect[0], startAngle, spanAngle);    // 绘制扇形
            painter.restore();
        }
    }
}

void Widget::paintWendu()
{
    int high[6] = {};
    int low[6] = {};
    int tempTotal = 0;

    QString h,l;
    for(int i = 0; i < 6; i++) {
        h = forecast[i].high.split(" ").at(1);
        h = h.left(h.length() - 1);
        high[i] = (int)h.toDouble();
        tempTotal += high[i];

        l = forecast[i].low.split(" ").at(1);
        l = l.left(l.length() - 1);
        low[i] = (int)l.toDouble();
    }

    int tempAverage = (int)(tempTotal/6);
    int pointX[6] = {34, 118, 195, 270, 345, 414};
    int pointHY[6] = {0};
    int pointLY[6] = {0};

    for(int i = 0; i < 6; i++) {
        pointHY[i] = TEPERATURE_START_HIGH - ((high[i] - tempAverage) * SPAN_INDEX);
        qDebug() << pointHY[i];
        pointLY[i] = TEPERATURE_START_HIGH + ((tempAverage - low[i]) * SPAN_INDEX);
        qDebug() << pointLY[i];
    }

    // 绘制图形
    QPainter painter(ui->curveLB);
    painter.setRenderHint(QPainter::Antialiasing, true);  // 反锯齿
    QPen pen = painter.pen();
    pen.setWidth(1);
    painter.setPen(pen);
    painter.save();

    // 绘制高温折线
    pen.setColor(QColor(255, 170, 0));
    pen.setStyle(Qt::DotLine);
    painter.setPen(pen);
    painter.setBrush(QColor(255, 170, 0));

    painter.drawEllipse(QPoint(pointX[0], pointHY[0]), ORIGIN_SIZE, ORIGIN_SIZE);
    painter.drawEllipse(QPoint(pointX[1], pointHY[1]), ORIGIN_SIZE, ORIGIN_SIZE);
    painter.drawLine(pointX[0], pointHY[0], pointX[1], pointHY[1]);

    painter.restore();
    painter.save();
    pen.setStyle(Qt::SolidLine);
    painter.setPen(pen);

    for(int i = 1; i < 5; i++) {
        painter.drawEllipse(QPoint(pointX[i + 1], pointHY[i + 1]), ORIGIN_SIZE, ORIGIN_SIZE);
        painter.drawLine(pointX[i], pointHY[i], pointX[i + 1], pointHY[i + 1]);
    }
    painter.restore();
    painter.save();

    // 绘制低温折线
    pen.setColor(QColor(0, 255, 255));
    pen.setStyle(Qt::DotLine);
    painter.setPen(pen);
    painter.setBrush(QColor(0, 255, 255));

    painter.drawEllipse(QPoint(pointX[0], pointLY[0]), ORIGIN_SIZE, ORIGIN_SIZE);
    painter.drawEllipse(QPoint(pointX[1], pointLY[1]), ORIGIN_SIZE, ORIGIN_SIZE);
    painter.drawLine(pointX[0], pointLY[0], pointX[1], pointLY[1]);

    painter.restore();
    painter.save();
    pen.setStyle(Qt::SolidLine);
    painter.setPen(pen);

    for(int i = 1; i < 5; i++) {
        painter.drawEllipse(QPoint(pointX[i + 1], pointLY[i + 1]), ORIGIN_SIZE, ORIGIN_SIZE);
        painter.drawLine(pointX[i], pointLY[i], pointX[i + 1], pointLY[i + 1]);
    }
    painter.restore();
}

bool Widget::eventFilter(QObject *watched, QEvent *event)
{
    // 绘制日出日落图
    if(watched == ui->sunRiseSetLB && event->type() == QEvent::Paint) {
        paintSunRiseSet();
    } else if(watched == ui->curveLB && event->type() == QEvent::Paint) {
        paintWendu();
    }
    return QWidget::eventFilter(watched, event);
}

Widget::~Widget()
{
    delete ui;
}

// 搜索功能
void Widget::on_toolButton_clicked()
{
    cityTmp = city;
    city = ui->cityLineEdit->text();
    getWeatherInfo(manager);
}

// 刷新
void Widget::on_toolButton_2_clicked()
{
    getWeatherInfo(manager);
    ui->curveLB->update();  // 触发系统paint函数
}

